﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace GFluentCode.Tools
{
    /// <summary>
    /// 文件变化监听帮助类
    /// </summary>
    public class FileWatcher
    {
        public delegate void FileChangedHandler(FileSystemWatcher sender, string fileName, string fullPath);
        public static event FileChangedHandler FileChanged;

        static Lazy<Dictionary<string, FileSystemWatcher>> _dicWatcher = new Lazy<Dictionary<string, FileSystemWatcher>>();

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="watcherName"></param>
        /// <param name="watcherPath"></param>
        /// <param name="fileter"></param>
        /// <param name="isInclude"></param>
        public static void Init(string watcherName, string watcherPath, string fileter, bool isInclude)
        {
            if (_dicWatcher.Value.ContainsKey(watcherName)) throw new Exception("已存在文件监控");

            var watcher = new FileSystemWatcher();

            watcher.BeginInit();

            watcher.Filter = fileter;
            watcher.IncludeSubdirectories = isInclude;
            watcher.EnableRaisingEvents = true;

            watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite;
            watcher.Path = watcherPath;

            watcher.Changed += WatcherChanged;

            watcher.EndInit();

            _dicWatcher.Value.Add(watcherName, watcher);
        }

        /// <summary>
        /// 停止文件监控
        /// </summary>
        /// <param name="watcherName"></param>
        public static void StopWatch(string watcherName)
        {
            if (!_dicWatcher.Value.ContainsKey(watcherName)) return;

            _dicWatcher.Value[watcherName].EnableRaisingEvents = false;
            _dicWatcher.Value[watcherName].Changed -= WatcherChanged;

            _dicWatcher.Value[watcherName].Dispose();

            _dicWatcher.Value.Remove(watcherName);
        }

        static void WatcherChanged(object sender, FileSystemEventArgs e)
        {
            var watcher = sender as FileSystemWatcher;

            //EnableRaisingEvents先关闭再打开，解决触发多次问题
            watcher.EnableRaisingEvents = false;

            FileChanged?.Invoke(watcher, e.Name, e.FullPath);

            watcher.EnableRaisingEvents = true;
        }
    }
}
